<?php
namespace App\Service\Volidate;

/**
 * @author chenshubo
 * 创建订单请求参数校验器
 */
use App\Service\Code\Normal;

class OrderCreateVolidate 
{
    //限制下单数量
    CONST ORDER_SIZE = 50 ;
    
    public $limit_user = [
        'jd' => '京东商户'
    ];
    
    //敏感信息用户
    public static $sensitive_user = [
        'pdd'   => '拼多多',
        'jd'    => '京东'
    ];
    
    //需要下游发起重新推送操作渠道商
    public static $retry_pay_user = [
        'pdd'   => '拼多多',
        'jd'    => '京东'
    ];
    
    /**
     * 校验输入参数
     * @param array $param
     */
    public static function checkParametersByRequest( $input = [] )
    {
        $param = $input['requestData'];
        $binfo = $input['binfo'];
        if( empty($param['goods']) ) {
            return Normal::returnCode(Normal::FAIL,"goods商品组不能为空");
        }
        
        $goodsList   = $param['goods'];
        if( !is_array($goodsList) ) {
            return Normal::returnCode(Normal::FAIL,"goods不是数组对象");
        }
        
        if( count($goodsList) > self::ORDER_SIZE ) {
            return Normal::returnCode(Normal::FAIL,"商品组不能超过".(self::ORDER_SIZE)."个");
        }
        
        if( empty($param['orderSn']) ) {
            return Normal::returnCode(Normal::FAIL,"orderSn订单号不能为空");
        }
        
        if( empty($param['buyerRealName']) ) {
            return Normal::returnCode(Normal::FAIL,"buyerRealName付款人真实姓名不能为空");
        }
        
        if( empty($param['buyerPhone']) ) {
            return Normal::returnCode(Normal::FAIL,"buyerPhone付款人电话不能为空");
        }
        
        if( empty($param['receiveName']) ) {
            return Normal::returnCode(Normal::FAIL,"receiveName收货人不能为空");
        }
        
        if( empty($param['recveivePhone']) ) {
            return Normal::returnCode(Normal::FAIL,"recveivePhone收货电话人不能为空");
        }
        
        if( empty($param['receiveAddress']) ) {
            return Normal::returnCode(Normal::FAIL,"receiveAddress收货地址不能为空");
        }
        
       /*  if( empty($param['buyerIdCard'])) {
            return Normal::returnCode(Normal::FAIL,"buyerIdCard付款人身份证号");
        } */
        
        if( empty($param['province']) ) {
            return Normal::returnCode(Normal::FAIL,"province省份不能为空");
        }
        
        if( empty($param['city']) ) {
            return Normal::returnCode(Normal::FAIL,"city市不能为空");
        }
        
        if( !isset($param['district']) ) {
            return Normal::returnCode(Normal::FAIL,"district地级区不能为空");
        }
        
        if( !empty($param['orderRemarks']) ) {
            $param['orderRemarks'] = checkFields($param['orderRemarks']);
        }
        
        if( !empty($param['orderSource']) ) {
            $param['orderSource'] = checkFields($param['orderSource']);
        }
        
        //是否使用优先级仓库商品扣除库存逻辑
        if( !empty($param['ignorePriority']) ) {
            $param['ignorePriority'] = checkFields($param['ignorePriority']);
        }
        
        //过滤指定字段
        $orderSn = checkFields($param['orderSn']);
        
        //如果是存在铭感信息加密之后的字段，则不检查下单字段规则问题
        if( ! (isset($param['extends']['orderType']) && isset(self::$sensitive_user[strtolower($param['extends']['orderType'])]) ) ) {
            $param['buyerRealName']     = checkFields($param['buyerRealName']);
            $param['buyerPhone']        = checkFields($param['buyerPhone']);
            $param['receiveName']       = checkFields($param['receiveName']);
            $param['recveivePhone']     = checkFields($param['recveivePhone']);
            $param['receiveAddress']    = checkFields($param['receiveAddress']);
            $param['buyerIdCard']       = checkFields($param['buyerIdCard']??'');
        }
        
        $param['province']          = checkFields($param['province']);
        $param['city']              = checkFields($param['city']);
        $param['district']          = checkFields($param['district']);
        
        //是否属于敏感信息渠道订单用户
        $isSensitive = isset(self::$sensitive_user[$binfo['user_tag']]) ? true : false;
        
        //需要校验正常下单渠道用户信息情况
        if ( !$isSensitive ) {
            //验证身份号码
            /* if( !checkIdCard($param['buyerIdCard'])) {
                return Normal::returnCode(Normal::FAIL,"buyerIdCard付款人身份证号格式不正确");
            } */
            
            //验证订单号
            if( $orderSn != $param['orderSn'] || strlen($param['orderSn']) > 50 ) {
                return Normal::returnCode(Normal::FAIL,"orderSn订单号只能为 50位以内的数字或字母");
            }
            
            //验证下单人
            if( !checkRealName($param['buyerRealName']) ) {
                return Normal::returnCode(Normal::FAIL,"buyerRealName付款人真实姓名格式不正确");
            }
            
            //验证号码
            if( !(checkPhone($param['buyerPhone']) || checkCallPhone($param['buyerPhone'])) ) {
                return Normal::returnCode(Normal::FAIL,"buyerPhone付款人电话格式不正确");
            }
            
            //验证号码
            if( !(checkPhone($param['recveivePhone']) || checkCallPhone($param['recveivePhone'])) ) {
                return Normal::returnCode(Normal::FAIL,"收货人电话格式不正确");
            }
        }
        
        //验证商品下单商品组
        if( empty($param['goods']) || !is_array($param['goods']) ) {
            return Normal::returnCode(Normal::FAIL,"下单商品组goods不能为空");
        }
        
        //运费
        $freight    = $param['freight'] ?? 0.00 ;
        $hasFreight = 0;
        //优惠金额
        $discountMoney = $param['discountMoney'] ?? 0.00;
        
        if( bccomp((string)$discountMoney,'0.00',2) == -1 ) {
            return Normal::returnCode(Normal::FAIL,"订单优惠金额discountMoney不能小于0");
        }
        
        if( bccomp((string)$freight,'0.00',2) == -1 ) {
            return Normal::returnCode(Normal::FAIL,"运费金额freight不能小于0");
        }
        
        //计算订单总金额
        $goodsTotalMoney = '0.00';
        foreach ($param['goods'] as $key => & $value )
        {
            if( !isset($value['goodsBatchNo']) ) {
                return Normal::returnCode(Normal::FAIL,"goodsBatchNo参数缺失");
            }
        
            if( empty($value['goodsSku']) ) {
                return Normal::returnCode(Normal::FAIL,"goodsSku商品sku不能为空");
            }
        
            if( empty($value['goodsNum']) ) {
                return Normal::returnCode(Normal::FAIL,"goodsNum购买数量不能为空");
            }
        
            if( empty($value['goodsPrice']) ) {
                return Normal::returnCode(Normal::FAIL,"goodsPrice商品价格不能为空");
            }
        
            if( empty($value['goodsSpecNum']) ) {
                return Normal::returnCode(Normal::FAIL,"goodsSpecNum商品规格数量不能为空");
            }
            
            //验证自编码
            if( !checkOnlyDC($value['goodsSku']) ) {
                //return Normal::returnCode(Normal::FAIL,"goodsSku只能为数字或者字母");
            }
            
            //验证单价
            if( !floatCheck($value['goodsPrice']) ) {
                return Normal::returnCode(Normal::FAIL,"goodsPrice商品单价格式不正确，必须0.00");
            }
            
            //验证数量
            if( !intNumberChcek($value['goodsNum']) ) {
                return Normal::returnCode(Normal::FAIL,"goodsNum商品数量必须为正整数");
            }
            
            //规格数量
            if( !intNumberChcek($value['goodsSpecNum']) ) {
                return Normal::returnCode(Normal::FAIL,"goodsSpecNum商品数量必须为正整数");
            }
            
            $goodsTotalMoney = bcadd((string)bcmul((string)$value['goodsPrice'],(string)$value['goodsNum'],2),(string)$goodsTotalMoney,2);
        }
        
        //订单金额         
        $orderMoney = bcadd((string)$goodsTotalMoney,(string)$freight,2);
        
        //验证商品组参数是否正确
        $goodsTotalPrice = 0 ;
        foreach ($param['goods'] as $key => & $value ) 
        {
            //商品goodsBatchNo
            $value['goodsBatchNo']  = checkFields($value['goodsBatchNo']);
            //商品Sku
            $value['goodsSku']      = checkFields($value['goodsSku']);
            //购买数量
            $value['goodsNum']      = checkFields($value['goodsNum']);
            //规格价格
            $value['goodsPrice']    = (float)checkFields($value['goodsPrice']);
            //商品税
            $goodsTax               = isset($value['goodsTax']) ? $value['goodsTax'] :  0 ;
            $value['goodsTax']      = (float)checkFields($goodsTax);
        
            $singlePrice            = bcadd($value['goodsPrice'], $value['goodsTax'],2);
            $currentGoodsTotalPrice = bcmul($value['goodsNum'], $singlePrice,2);
            $goodsTotalPrice        = bcadd($goodsTotalPrice,$currentGoodsTotalPrice ,2);
            
            //均摊运费
            if( $key == count($param['goods']) - 1 ) {
                $value['discountMoney'] = $discountMoney;
                $delivery_money = bcsub((string)$freight, $hasFreight,2);
            } else {
                $value['discountMoney'] = '0.00';
                $scale = bcdiv((string)$currentGoodsTotalPrice,(string)$orderMoney,4);
                $delivery_money = bcmul((string)$freight, (string)$scale,2);
                $hasFreight = bcadd((string)$hasFreight, $delivery_money,2);
            }
            
            $value['freight'] = $delivery_money;
        
            //规格数量
            $value['goodsSpecNum']  = checkFields($value['goodsSpecNum']);
        
            //保质期起始日期
            $startExpDate = isset($value['startExpDate']) ? $value['startExpDate'] : '';
            $value['startExpDate']  = checkFields($startExpDate);
            
            //保质期结束日期
            $endExpDate = isset($value['endExpDate']) ? $value['endExpDate'] : '';
            $value['endExpDate']    = checkFields($endExpDate);
        }
        
        //处理特殊字段
        $param['orderRemarks']      = $param['orderRemarks'] ?? '';
        $param['freight']           = $param['freight'] ?? 0.00;
        $param['freightTax']        = $param['freightTax'] ?? 0.00;
        $param['discountMoney']     = $param['discountMoney'] ?? 0.00;
        
        //校验订单金额是否正确
        $freight                    = $param['freight'] ?? 0.00;
        $freightTax                 = $param['freightTax'] ?? 0.00;
        
        //所有运费
        $checkTotalMoney    = bcadd($freight, $freightTax,2);
        //商品金额
        $checkTotalMoney    = bcadd($goodsTotalPrice, $checkTotalMoney,2);
        //订单总金额 = 所有运费 + 商品金额 - 优惠金额 
        $checkTotalMoney    = bcsub($checkTotalMoney,$discountMoney,2);
        
        //实际接口提交订单金额
        $orderMoney         = $param['orderMoney'];
        if( bccomp($orderMoney, $checkTotalMoney,2) !== 0 ) {
            return Normal::returnCode(Normal::FAIL,"订单实际支付金额orderMoney（{$orderMoney}）计算错误，订单金额计算公式【订单实际支付金额orderMoney（{$checkTotalMoney}）= 运费freight（{$freight}）+ 抵扣前商品行金额总和 sum(goodsNum*goodsPrice)（{$goodsTotalPrice}） - 非现金抵扣金额 discountMoney （{$discountMoney}）】");
        }
        
        //下单类型字段
        if( isset($param['orderType']) && !empty($param['orderType']) ) {
            $param['order_type'] = $param['orderType'];
            unset($param['orderType']);
        }
        
        $input['requestData'] = $param;
        return Normal::returnCode(Normal::SUC,"验证通过",$input);
        
    }
}